package cate.game.role.bag.furniture;

import cate.common.table.d.GDObj;
import cate.common.table.item.furniture.row.FurnitureItemBaseRow;
import cate.common.util.XT;
import cate.game.GameBody;
import cate.game.play.support.PlayBuildContext;
import cate.game.role.Role;
import cate.game.role.bag.item.BaseBagItem;
import cp.solution.pattern.ICopiable;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;

import java.util.List;

@NoteClass(value = "手办数据")
public class Furniture extends BaseBagItem implements ICopiable<Furniture> {
    @NoteField(value = "手办等级")
    public int level;
    @NoteField(value = "手办种族")
    public byte camp;
    @NoteField(value = "手办职业")
    public byte job;
    @NoteField(value = "阵营属性1")
    public int camp1AttrId;
    @NoteField("阵营属性2")
    public int camp2AttrId;
    @NoteField(value = "手办职业属性1")
    public int job1AttrId;
    @NoteField(value = "职业属性2")
    public int job2AttrId;
    @NoteField("通用属性")
    public int commonAttrId;

    @NoteField(value = "洗练缓存")
    public FurnitureRecastTemp reCast;

    public Furniture() {

    }

    public Furniture(Role role, int tid) {
        super(role, GDObj.Type.FURNITURE, tid, 1);
        genAttr();
        this.reCast = new FurnitureRecastTemp();
    }

    private void genAttr() {
        this.camp = 1;
        this.job = 1;
        FurnitureItemBaseRow baseRow = getTpl(role.toPlayBuildContext());
        if (baseRow != null) {
            this.camp = randomCamp(baseRow.camps);
            this.job = randomJob(baseRow.jobs);
            this.camp1AttrId = randomAttrId(role.getGame(), this.camp, baseRow.camp1Group);
            this.camp2AttrId = randomAttrId(role.getGame(), this.camp, baseRow.camp2Group);
            this.commonAttrId = randomAttrId(role.getGame(), (byte) 0, baseRow.commonGroup);
            this.job1AttrId = randomAttrId(role.getGame(), this.job, baseRow.job1Group);
            this.job2AttrId = randomAttrId(role.getGame(), this.job, baseRow.job2Group);
        }
    }

    public void recastAttr(byte camp, byte job, int newCampAttrId, int newJobAttrId) {
        FurnitureItemBaseRow baseRow = getTpl(role.toPlayBuildContext());
        if (baseRow != null) {
            //全自选就让他选，不做属性重复判断
            boolean allCustomize = camp > 0 && job > 0 && newCampAttrId > 0 && newJobAttrId > 0;
            //只能变第一个id
            reCast.camp = camp > 0 ? camp : randomCamp(baseRow.camps);
            reCast.job = job > 0 ? job : randomJob(baseRow.jobs);
            reCast.camp1AttrId = newCampAttrId > 0 ? newCampAttrId : randomAttrId(role.getGame(), reCast.camp, baseRow.camp1Group);
            reCast.camp2AttrId = randomAttrId(role.getGame(), reCast.camp, baseRow.camp2Group);
            reCast.job1AttrId = newJobAttrId > 0 ? newJobAttrId : randomAttrId(role.getGame(), reCast.job, baseRow.job1Group);
            reCast.job2AttrId = randomAttrId(role.getGame(), reCast.job, baseRow.job2Group);
            reCast.commonAttrId = randomAttrId(role.getGame(), (byte) 0, baseRow.commonGroup);
            //如果随机出来的阵营，职业，阵营属性还是和之前一样的话， 职业属性就一定要变
            if (!allCustomize &&
                    reCast.camp == this.camp
                    && reCast.job == this.job
                    && reCast.camp1AttrId == this.camp1AttrId) {
                reCast.job1AttrId = randomAttrExcludeOne(role.getGame(), baseRow.job1Group, reCast.job, this.job1AttrId);
            }
            if (allCustomize) {
                save();
            }
        }
    }

    public void save() {
        if (reCast.isEmpty()) {
            return;
        }
        this.camp = reCast.camp;
        this.job = reCast.job;
        this.camp1AttrId = reCast.camp1AttrId;
        this.camp2AttrId = reCast.camp2AttrId;
        this.job1AttrId = reCast.job1AttrId;
        this.job2AttrId = reCast.job2AttrId;
        this.commonAttrId = reCast.commonAttrId;
        reCast.clear();
    }

    private byte randomJob(List<Byte> jobs) {
        if (jobs.isEmpty()) {
            return 0;
        }
        return jobs.get(XT.randomIndex(jobs.size()));
    }

    private byte randomCamp(List<Byte> camps) {
        if (camps.isEmpty()) {
            return 0;
        }
        return camps.get(XT.randomIndex(camps.size()));
    }

    private int randomAttrId(GameBody game, byte limit, int group) {
        if (group == 0) {
            return 0;
        }
        return game.table.furniture.randomAttr.randomAttr(group, limit).id;
    }

    private int randomAttrExcludeOne(GameBody game, int group, byte limit, int excludeId) {
        return game.table.furniture.randomAttr.randomAttrExcludeOne(group, limit, excludeId).id;
    }

    @Override
    public FurnitureItemBaseRow getTpl(PlayBuildContext ctx) {
        return ctx.furnitureExcel().base.get(tid);
    }

    @Override
    public FurnitureItemBaseRow getTpl(GameBody game) {
        return getTpl(game.fight.getPlayBuildContext());
    }

    @Override
    public String toDetail() {
        return level + "|" + camp + "|" + job;
    }

    @Override
    public Furniture copy() {
        Furniture cp = new Furniture();
        super.copy(cp);
        cp.level = level;
        cp.job = job;
        cp.camp = camp;
        cp.camp1AttrId = camp1AttrId;
        cp.camp2AttrId = camp2AttrId;
        cp.job1AttrId = job1AttrId;
        cp.job2AttrId = job2AttrId;
        cp.commonAttrId = commonAttrId;
        return cp;
    }
}
